package cn.tedu.medicalappointmentsystemk.service.impl;

import cn.tedu.medicalappointmentsystemk.dao.persist.repository.*;
import cn.tedu.medicalappointmentsystemk.handler.ServiceException;
import cn.tedu.medicalappointmentsystemk.pojo.bo.DoctorSelectBO;
import cn.tedu.medicalappointmentsystemk.pojo.bo.DoctorSelectByDoctorIdBO;
import cn.tedu.medicalappointmentsystemk.pojo.bo.DoctorSelectByIdBO;
import cn.tedu.medicalappointmentsystemk.pojo.bo.DoctorSelectTypeBO;
import cn.tedu.medicalappointmentsystemk.pojo.param.DoctorAddParam;
import cn.tedu.medicalappointmentsystemk.pojo.param.DoctorUpdateParam;
import cn.tedu.medicalappointmentsystemk.pojo.po.*;
import cn.tedu.medicalappointmentsystemk.response.ServiceCode;
import cn.tedu.medicalappointmentsystemk.service.DoctorService;
import cn.tedu.medicalappointmentsystemk.util.PageInfoToPageDataConverter;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class DoctorServiceImpl implements DoctorService {
    @Autowired
    private DoctorRepository doctorRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private DoctorDepartmentRepository doctorDepartmentRepository;

    @Autowired
    private UserRoleRepository userRoleRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private PatientRepository patientRepository;

    @Value("${medical.dao.default-query-page-size}")
    private int pageSize;

    @Override
    public void addDoctor(DoctorAddParam doctorAddParam) {
        {
            String mobile = doctorAddParam.getMobile();
            Integer count = userRepository.countByMobile(mobile);
            if (count > 0) {
                String message = "添加用户失败,手机号码已经被占用!";
                log.error(message);
                throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
            }
        }
        {
            String email = doctorAddParam.getEmail();
            Integer count = userRepository.countByEmail(email);
            if (count > 0) {
                String message = "添加用户失败,电子邮箱已经被占用!";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
            }
        }
        UserPO po = new UserPO();
        BeanUtils.copyProperties(doctorAddParam, po);
        po.setUsername("JSD" + new Date().getTime());
        po.setPassword(passwordEncoder.encode("123456"));
        po.setEnable(ENABLE_STATE_ON);
        Integer row = userRepository.addNew(po);
        if (row != 1) {
            String message = "注册失败!";
            log.error(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT,message);
        }
        Long userId = userRepository.selectIdByUsername(po.getUsername());
        PatientPO patient = new PatientPO();
        patient.setUserId(userId);
        row = patientRepository.addNew(patient);
        if (row != 1){
            String message = "注册失败!";
            log.error(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT,message);
        }
        DoctorPO Dpo = new DoctorPO();
        BeanUtils.copyProperties(doctorAddParam, Dpo);
        Dpo.setCreateUser(userRepository.selectNicknameById(doctorAddParam.getUserId()));
        Dpo.setUserId(userId);
        row = doctorRepository.addNew(Dpo);
        if (row != 1) {
            String message = "注册失败!";
            log.error(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT,message);
        }
        DoctorDepartmentPO DDpo = new DoctorDepartmentPO();
        DDpo.setDoctorId(doctorRepository.selectIdByUserId(Dpo.getUserId()));
        DDpo.setDepartmentId(doctorAddParam.getDepartmentId());
        row = doctorDepartmentRepository.addNew(DDpo);
        if (row != 1) {
            String message = "注册失败!";
            log.error(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT,message);
        }
        UserRolePO Upo = new UserRolePO();
        Upo.setUserId(Dpo.getUserId());
        Upo.setRoleId(2L);
        row = userRoleRepository.insert(Upo);
        if (row != 1) {
            String message = "注册失败!";
            log.error(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT,message);
        }
    }

    @Override
    public PageData<DoctorSelectBO> selectDoctor(Integer pageNum) {
        PageHelper.startPage(pageNum,pageSize);
        Page<DoctorSelectBO> page = doctorRepository.select();
        PageInfo<DoctorSelectBO> pageInfo = new PageInfo<>(page);
        return PageInfoToPageDataConverter.convert(pageInfo);
    }

    @Override
    public void deleteDoctor(Long id) {
        DoctorPO po = doctorRepository.selectById(id);
        Integer row = userRepository.deleteById(po.getUserId());
        if (row != 1) {
            String message = "删除失败!";
            log.error(message);
            throw new ServiceException(ServiceCode.ERROR_DELETE,message);
        }
        row = doctorDepartmentRepository.deleteByDoctorId(po.getId());
        if (row != 1) {
            String message = "删除失败!";
            log.error(message);
            throw new ServiceException(ServiceCode.ERROR_DELETE,message);
        }
        row = doctorRepository.deleteById(po.getId());
        if (row != 1) {
            String message = "删除失败!";
            log.error(message);
            throw new ServiceException(ServiceCode.ERROR_DELETE,message);
        }
    }

    @Override
    public DoctorSelectByIdBO selectDoctorById(Long id) {
        DoctorSelectByIdBO bo = new DoctorSelectByIdBO();
        DoctorPO Dpo = doctorRepository.selectById(id);
        UserPO po = userRepository.selectById(Dpo.getUserId());
        bo.setDepartmentId(doctorDepartmentRepository.selectByDoctorId(id).getDepartmentId());
        BeanUtils.copyProperties(po, bo);
        BeanUtils.copyProperties(Dpo, bo);
        return bo;
    }

    @Override
    public List<DoctorSelectTypeBO> selectDoctorType() {
        List<DoctorSelectBO> listBOS = doctorRepository.select();
        List<DoctorSelectTypeBO> listBO = new ArrayList<>();
        for (DoctorSelectBO bo : listBOS) {
            DoctorSelectTypeBO bos = new DoctorSelectTypeBO();
            BeanUtils.copyProperties(bo,bos);
            listBO.add(bos);
        }
        return listBO;
    }

    @Override
    public void changeDoctor(DoctorUpdateParam param) {
        Integer row = doctorRepository.update(param);
        if (row == 0){
            String message = "更新失败!";
            log.error(message);
            throw new ServiceException(ServiceCode.ERROR_UPDATE,message);
        }
    }

    @Override
    public DoctorSelectByDoctorIdBO selectDoctorByDoctorId(Long id) {
        return doctorRepository.selectDoctorByDoctorId(id);
    }

    @Override
    public List<DoctorSelectBO> selectByNickname(String nickname) {
        return doctorRepository.selectByNickname(nickname);
    }

    @Override
    public Integer selectTotal() {
        return doctorRepository.selectTotal();
    }

    @Override
    public PageData<DoctorSelectBO> searchLastWeek(Integer pageNum) {
        PageHelper.startPage(pageNum,pageSize);
        Page<DoctorSelectBO> page = doctorRepository.searchLastWeek();
        PageInfo<DoctorSelectBO> pageInfo = new PageInfo<>(page);
        return PageInfoToPageDataConverter.convert(pageInfo);
    }

    @Override
    public PageData<DoctorSelectBO> searchLastMonth(Integer pageNum) {
        PageHelper.startPage(pageNum,pageSize);
        Page<DoctorSelectBO> page = doctorRepository.searchLastMonth();
        PageInfo<DoctorSelectBO> pageInfo = new PageInfo<>(page);
        return PageInfoToPageDataConverter.convert(pageInfo);
    }

    @Override
    public PageData<DoctorSelectBO> searchToday(Integer pageNum) {
        PageHelper.startPage(pageNum,pageSize);
        Page<DoctorSelectBO> page = doctorRepository.searchToday();
        PageInfo<DoctorSelectBO> pageInfo = new PageInfo<>(page);
        return PageInfoToPageDataConverter.convert(pageInfo);
    }
}
